package tr.edu.metu.is.mega.client.course.instructor;

import java.util.List;

import tr.edu.metu.is.mega.client.core.AsyncCallbackAdapter;
import tr.edu.metu.is.mega.client.core.AuthUtils;
import tr.edu.metu.is.mega.client.core.DialogCallbackAdapter;
import tr.edu.metu.is.mega.client.core.MainWindow;
import tr.edu.metu.is.mega.client.core.QueryCallback;
import tr.edu.metu.is.mega.client.core.event.SelectionEventBus;
import tr.edu.metu.is.mega.client.core.event.SelectionEventListener;
import tr.edu.metu.is.mega.client.course.CourseChangeEvent;
import tr.edu.metu.is.mega.client.course.activity.ActivityManagementPanel;
import tr.edu.metu.is.mega.client.course.activity.ScheduleManagementDialog;
import tr.edu.metu.is.mega.client.course.admin.CourseDefinitionDialog;
import tr.edu.metu.is.mega.client.course.announcement.AnnouncementManagementPanel;
import tr.edu.metu.is.mega.client.course.instructor.students.CourseStudentsManagementDialog;
import tr.edu.metu.is.mega.client.course.instructor.students.TeamManagementPanel;
import tr.edu.metu.is.mega.client.course.lecturenote.LectureNoteManagementPanel;
import tr.edu.metu.is.mega.client.service.GwtCourseService;
import tr.edu.metu.is.mega.client.service.GwtCourseServiceAsync;
import tr.edu.metu.is.mega.common.dto.CourseDTO;
import tr.edu.metu.is.mega.common.dto.UserDTO;
import tr.edu.metu.is.mega.common.dto.UserRole;

import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.ColumnData;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.extjs.gxt.ui.client.widget.layout.FillData;
import com.extjs.gxt.ui.client.widget.layout.FillLayout;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.History;

/**
 * Main window to manage course informations.
 */
public class CourseInformationWindow extends MainWindow {

    private CourseDTO course;

    private ToolBar toolBar;

    /**
     * Default constructor.
     */
    public CourseInformationWindow() {
        super("CourseInformationWindow", null);
        setHeading("Course Information");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onRender(Element parent, int pos) {
        super.onRender(parent, pos);
        setLayout(new FillLayout());
        setSize(1024, 768);
        ContentPanel panel = new ContentPanel();
        panel.setLayout(new RowLayout());
        panel.setHeaderVisible(false);
        panel.setBodyBorder(false);

        CourseInformationPanel courseInformationPanel = new CourseInformationPanel();

        panel.add(courseInformationPanel, new RowData(1, -1, new Margins(10)));

        LayoutContainer middlePanel = new LayoutContainer(new ColumnLayout());
        TeamManagementPanel teamManagementPanel = new TeamManagementPanel();
        teamManagementPanel.setStyleAttribute("paddingRight", "10px");
        middlePanel.add(teamManagementPanel, new ColumnData(0.4));
        middlePanel.add(new ActivityManagementPanel(UserRole.INSTRUCTOR), new ColumnData(0.6));

        panel.add(middlePanel, new RowData(1, -1, new Margins(10)));

        LayoutContainer bottomPanel = new LayoutContainer(new ColumnLayout());
        LectureNoteManagementPanel lectureNoteManagementPanel = new LectureNoteManagementPanel(UserRole.INSTRUCTOR);
        lectureNoteManagementPanel.setStyleAttribute("paddingRight", "10px");
        bottomPanel.add(lectureNoteManagementPanel, new ColumnData(0.4));
        bottomPanel.add(new AnnouncementManagementPanel(UserRole.INSTRUCTOR), new ColumnData(0.6));

        panel.add(bottomPanel, new RowData(1, -1, new Margins(0, 10, 10, 10)));

        panel.setTopComponent(getToolBar());
        add(panel, new FillData());

        SelectionEventBus.getInstance().registerListener(CourseChangeEvent.Update.class, new SelectionEventListener<CourseDTO>() {

            @Override
            public void selectionChanged(CourseDTO selectedObject) {
                course = selectedObject;
            }
        });

    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void afterRender() {
        super.afterRender();
        String[] split = History.getToken().split(":");
        if (split.length == 2) {
            CourseDTO course = new CourseDTO();
            course.setPkid(Integer.valueOf(split[1]));
            GwtCourseService.Util.getInstance().getCourses(course, new AsyncCallbackAdapter<List<CourseDTO>>() {

                @Override
                public void onSuccess(List<CourseDTO> result) {
                    if (result.size() == 1) {
                        SelectionEventBus.getInstance().fireEvent(CourseChangeEvent.UPDATE, result.get(0));
                    }
                }

            });
        }
        AuthUtils.getInstance().getCurrentUser(new QueryCallback<UserDTO>() {

            @Override
            public void onQueryResult(UserDTO result) {
                if (result.getRole() == UserRole.ASSISTANT) {
                    toolBar.setEnabled(false);
                }
            }
        });
    }

    /**
     * Initializes and returns toolbar.
     * 
     * @return toolbar
     */
    public ToolBar getToolBar() {

        toolBar = new ToolBar();

        Button manageStudentsButton = new Button("Manage Students");

        manageStudentsButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (course != null) {
                    CourseStudentsManagementDialog dialog = new CourseStudentsManagementDialog(course);
                    dialog.show();
                } else {
                    Info.display("", "Choose course first");
                }
            }
        });

        Button editCourseInformationButton = new Button("Edit Course Information");

        editCourseInformationButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (course != null) {
                    CourseDefinitionDialog dialog = new CourseDefinitionDialog();

                    dialog.update(course, new DialogCallbackAdapter<CourseDTO>() {

                        @Override
                        public void onOk(CourseDTO param) {
                            getService().updateCourse(param, new AsyncCallbackAdapter<CourseDTO>() {

                                @Override
                                public void onSuccess(CourseDTO result) {
                                    SelectionEventBus.getInstance().fireEvent(CourseChangeEvent.UPDATE, result);
                                }
                            });
                        }
                    });
                }
            }
        });

        Button manageScheduleButton = new Button("Manage Schedule");

        manageScheduleButton.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent ce) {
                if (course != null) {
                    ScheduleManagementDialog dialog = new ScheduleManagementDialog(course);
                    dialog.show();
                } else {
                    Info.display("", "Choose course first");
                }
            }
        });

        toolBar.add(manageStudentsButton);
        toolBar.add(editCourseInformationButton);
        toolBar.add(manageScheduleButton);

        return toolBar;

    }

    /**
     * Returns GWT course service instance.
     * 
     * @return GWT service
     */
    public static GwtCourseServiceAsync getService() {
        return GwtCourseService.Util.getInstance();
    }

}
